#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pprint import pprint
import json

class Tree():
    def __init__(self):
        self.__root = Node()

    def AddPatterns(self, *Patterns):
        """TODO: Docstring for AddPatterns.

        :*Patterns: TODO
        :returns: TODO

        """
        for pattern in Patterns:
            cur_node = self.__root
            for ch in pattern:
                cur_node = cur_node.AddGotoNode(ch)
            cur_node.AddOutput(pattern)

        self.__root.AddFailNode(self.__root)
        self.__root.ConstructionFail(self.__root)


    def Print(self, arg1):
        """TODO: Docstring for Print.

        :arg1: TODO
        :returns: TODO

        """
        print(self.__root)

    def Matching(self, text):
        """TODO: Docstring for Matching.

        :text: TODO
        :returns: TODO

        """
        cur_node = self.__root
        for ch in text:
            cur_node = cur_node.NextNode(ch)


class Node():

    """Docstring for Node. """

    def __repr__ (self):
        """TODO: Docstring for __repr__ .
        :returns: TODO

        """
        return "{" + "fail:" + str(self.__fail.__character) + ", isbole:" + str(self.__isbole) + ", goto:" + str(self.__goto) + "}"

    def __init__(self, is_bole = True, character = None):
        """TODO: to be defined1. """
        self.__goto = {}
        self.__fail = None
        self.__output = None
        self.__isbole = is_bole
        self.__character = character

    def AddGotoNode(self, character):
        """TODO: Docstring for AddGotoNode.

        :character: TODO
        :returns: TODO

        """
        if character not in self.__goto.keys():
            cur_node = Node(self.__character is None, character)
            self.__goto[character] = cur_node
            return cur_node
        else:
            return self.__goto[character]

    def ConstructionFail(self, target_node):
        """TODO: Docstring for ConstructionFail.

        :target_node: TODO
        :returns: TODO

        """
        for node in self.__goto.values():
            node.AddFailNode(target_node)
        for node in self.__goto.values():
            node.ConstructionFail(node.__fail)

    def AddFailNode(self, target_node):
        """TODO: Docstring for AddFailNode.

        :target_node: TODO
        :returns: TODO

        """
        if self.__isbole:
            self.__fail = target_node
        elif self.__character in target_node.__goto.keys():
            self.__fail = target_node.__goto[self.__character]
        else:
            self.__fail = target_node.__fail

    def AddOutput(self, pattern):
        """TODO: Docstring for AddOutput.

        :pattern: TODO
        :returns: TODO

        """
        self.__output = pattern

    def NextNode(self, character):
        """TODO: Docstring for NextNode.

        :charactor: TODO
        :returns: TODO

        """
        node = self
        while True:
            node.PrintResult()
            if character in node.__goto.keys():
                return node.__goto[character]
            elif node.__character is None:
                return node

            node = node.__fail

    def PrintResult(self):
        """TODO: Docstring for PrintResult.
        :returns: TODO

        """
        if self.__output is not None:
            print(self.__output)


def main():
    t = Tree()
    t.AddPatterns(u'中国小说网', u'小说网有', u'小说网站', u'各种小说', u'网站')
    t.Matching(u'中国小说网是一个各种小说都有的小说网站，小说网有个类小说作家')

if __name__ == '__main__':
    main()
